// AboutDlg.cpp : implementation of the CDraftsDlg class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif
#include "draftsdlg.h"
#include "DraftInfoDlg.h"

CDraftsDlg::CDraftsDlg(void)
    : m_DraftId(0)
    , m_SelectMode(false)
{
}

LRESULT CDraftsDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    AtlCreateMenuBar(m_hWnd, IDM_NEW_DELETE);

#ifdef WIN32_PLATFORM_WFSP
    if (hMenuBar != NULL)
        AtlActivateBackKey(hMenuBar);
#endif

    BOOL Ret = m_ImageList.Create(32, 32, ILC_COLORDDB | ILC_MASK, 2, 0);
    ATLASSERT(Ret == TRUE);

    CIcon icon;
    icon.LoadIcon(IDI_DRAFTS);
    int Result = m_ImageList.AddIcon(icon);
    ATLASSERT(Result != -1);
    icon.DestroyIcon();

    m_List.Attach(GetDlgItem(IDC_LIST));
    m_List.SetImageList(m_ImageList, LVSIL_SMALL);

    CRect r;
    m_List.GetClientRect(&r);
    m_List.InsertColumn(INDEX_NAME, NULL, LVCFMT_LEFT, r.Width());
    if (m_SelectMode == false)
        m_List.InsertColumn(INDEX_OP, NULL, LVCFMT_RIGHT, r.Width());

    m_DraftsDb.Open();

    UINT i = 1;     // 0th is reserved for saving current draft
    CString Draft;
    UINT Id = 0;
    DWORD Err = m_DraftsDb.Get(i, &Id, &Draft);
    while (Err == ERROR_SUCCESS)
    {
        i++;
        AddDraft(Id, Draft);
        Err = m_DraftsDb.Get(i, &Id, &Draft);
    }

    if (m_List.GetItemCount() > 0)
    {
        m_List.SelectItem(0);
        m_List.EnsureVisible(0, FALSE);
    }

    return bHandled = FALSE;
}

LRESULT CDraftsDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    m_DraftId = ((Ret == TRUE) ? Item.lParam : 0);

    m_DraftsDb.Close();
    m_List.Detach();
    return bHandled = FALSE;
}

LRESULT CDraftsDlg::OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
    OnSize();
    return bHandled = FALSE;
}

void CDraftsDlg::OnSize(void)
{
    CRect r;
    m_List.GetClientRect(&r);

    float NameColWidth = m_SelectMode == true ? 1.0f : OP_SYMBOL_WIDTH;
    m_List.SetColumnWidth(INDEX_NAME, (int)(r.Width() * NameColWidth));
    if (m_SelectMode == false)
    {
        m_List.SetColumnWidth(
            INDEX_OP,
            (int)(r.Width() * (1.0f - NameColWidth)));
    }
}

LRESULT CDraftsDlg::OnListDblClick(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    ATLASSERT(idCtrl == IDC_LIST);
    NMLISTVIEW *nml = (NMLISTVIEW *)pnmh;

    if (m_SelectMode == true)
    {
        LVITEM Item = {0};
        Item.mask = LVIF_PARAM;
        Item.iItem = nml->iItem;
        Item.iSubItem = 0;
        m_List.GetItem(&Item);

        EditDraft(nml->iItem, Item.lParam);
    }

    return 0;
}

void CDraftsDlg::OnItem(int ItemId)
{
    if (m_SelectMode == true)
    {
        EndDialog(IDOK);
    }
    else
    {
        LVITEM Item = {0};
        Item.mask = LVIF_PARAM;
        Item.iItem = ItemId;
        Item.iSubItem = 0;
        m_List.GetItem(&Item);

        EditDraft(ItemId, Item.lParam);
    }
}

LRESULT CDraftsDlg::OnListClick(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CDraftsDlg::OnListReturn(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
    OnItem(((NMLISTVIEW *)pnmh)->iItem);
    return 0;
}

LRESULT CDraftsDlg::OnMenuNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    AddNewDraft();
    return 0;
}

void CDraftsDlg::AddNewDraft(void)
{
    CDraftInfoDlg dlg;
    int ret = dlg.DoModal();

    if (ret == ID_MENU_OK || ret == IDOK)
    {
        UINT AssignedId = 0;
        DWORD Err = m_DraftsDb.Add(dlg.GetDraft(), &AssignedId);
        if (Err != ERROR_SUCCESS)
        {
            ATLTRACE(_T("Add to database failed\n"));
            return;
        }

        AddDraft(AssignedId, dlg.GetDraft());
    }
}

void CDraftsDlg::AddDraft(UINT DraftId, CString &Draft)
{
    FormatDraft(&Draft);

    LVITEM Item = { 0 };
    Item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
    Item.iItem = m_List.GetItemCount();
    Item.iSubItem = INDEX_NAME;
    Item.pszText = (LPTSTR)((LPCTSTR)Draft);
    Item.iImage = 0;
    Item.lParam = DraftId;

    int NewIndex = m_List.InsertItem(&Item);
    if (NewIndex < 0)
    {
        ATLASSERT(!"InsertItem failed");
        return;
    }

    if (m_SelectMode == false)
    {
        Item.mask = LVIF_TEXT;
        Item.iItem = NewIndex;
        Item.iSubItem = INDEX_OP;
        Item.pszText = (TCHAR *)OP_SYMBOL;

        m_List.SetItem(&Item);
        m_List.SelectItem(NewIndex);
    }

    m_List.EnsureVisible(NewIndex, FALSE);
    m_List.SetFocus();

    OnSize();
}

void CDraftsDlg::EditDraft(int ListIndex, UINT DraftId)
{
    UINT DbIndex = 0;
    CString Draft;
    DWORD Err = m_DraftsDb.GetFromId(DraftId, &Draft, &DbIndex);
    if (Err == ERROR_SUCCESS)
    {
        CDraftInfoDlg dlg;
        dlg.SetDraft(Draft);
        int ret = dlg.DoModal();

        if (ret == ID_MENU_OK || ret == IDOK)
        {
            Draft = dlg.GetDraft();
            DWORD Err = m_DraftsDb.Set(DbIndex, Draft);
            if (Err == ERROR_SUCCESS)
            {
                FormatDraft(&Draft);
                m_List.SetItemText(ListIndex, 0, Draft);
            }
        }
    }
}

DWORD CDraftsDlg::FormatDraft(CString *pDraft)
{
    if (pDraft == NULL)
        return ERROR_INVALID_PARAMETER;

    pDraft->Replace(_T("\r\n"), _T(" "));
    return ERROR_SUCCESS;
}

LRESULT CDraftsDlg::OnMenuDelete(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    LVITEM Item = {0};
    Item.mask = LVIF_PARAM;
    BOOL Ret = m_List.GetSelectedItem(&Item);
    if (Ret == FALSE)
    {
        ATLTRACE(_T("No item selected to delete\n"));
        return 0;
    }

    UINT DbIndex = 0;
    CString Draft;
    DWORD Err = m_DraftsDb.GetFromId(Item.lParam, &Draft, &DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to get db index\n"));
        return 0;
    }

    Err = m_DraftsDb.Delete(DbIndex);
    if (Err != ERROR_SUCCESS)
    {
        ATLTRACE(_T("Unable to delete from db\n"));
        return 0;
    }

    m_List.DeleteItem(Item.iItem);

    int ItemCount = m_List.GetItemCount();
    if (ItemCount > 0)
    {
        if (Item.iItem >= ItemCount)
            Item.iItem--;

        m_List.SelectItem(Item.iItem);
    }

    OnSize();

    return 0;
}
